#pragma once
#include <iostream>
#include<memory>
#include<vector>
#include"message.hpp"
#include"LogLevel.hpp"
namespace ldcLOG
{
    class FormatItem
    {
        public:
        using ptr=std::shared_ptr<FormatItem>;
        virtual void format(std::ostream&out,Message&msg) =0;
        private:
    };
    class MsgFormatItem:public FormatItem
    {
        public:
        void format(std::ostream&out,Message&msg)override
        {
            out<<msg.payload_;
        }
    };
    class LevelFormatItem:public FormatItem
    {
        public:
        void format(std::ostream&out,Message&msg)override
        {
            out<<LogLevel::toString(msg.level_);
        }
        
    };
    class TimeFormatItem:public FormatItem
    {
        public:
        TimeFormatItem(const std::string&timefmt="%H:%M:%S"):time_fmt_(timefmt){}
        void format(std::ostream&out,Message&msg)override
        {
            struct tm t;
            localtime_r(&msg.time_,&t);
            char tmp[32]={0};
            strftime(tmp,32,time_fmt_.c_str(),&t);
            out<<tmp;

        }

        private:
        std::string time_fmt_;//%H:%M:%S
    };
    class FileFormatItem:public FormatItem
    {
        public:
        void format(std::ostream&out,Message&msg)override
        {
            out<<msg.file_;
        }

    };
    class LineFormatItem:public FormatItem
    {
        public:
        void format(std::ostream&out,Message&msg)override
        {
            out<<msg.line_;
        }

    };
    class ThreadFormatItem:public FormatItem
    {
        public:
        void format(std::ostream&out,Message&msg)override
        {
            out<<msg.tid_;
        }
        
    };
    class LoggerFormatItem:public FormatItem
    {
        public:
        void format(std::ostream&out,Message&msg)override
        {
            out<<msg.logger_;
        }

    };
    class TabFormatItem:public FormatItem
    {
        public:
        void format(std::ostream&out,Message&msg)override
        {
            out<<"\t";//?
        }

    };
    class NLineFormatItem:public FormatItem
    {
        public:
        void format(std::ostream&out,Message&msg)override
        {
            out<<"\n";//?
        }

    };
    class OtherFormatItem:public FormatItem
    {
        public:
        OtherFormatItem(const std::string&str):str_(str)
    {}
        void format(std::ostream&out,Message&msg)override
        {
            out<<str_;
        }
        private:
        std::string str_;
    };

    /*
    %d : 日期
    %t : 线程id
    %c : 日志器名称
    %f : 源文件名
    %l : 行号
    %p : 日志等级
    %T : 制表符缩进
    %m : 主体消息
    %n : 换行
    */
    class Formatter{
        public:
        Formatter(const std::string&pattern="[%d{%H:%M:%S}][%t][%c][%f:%l][%p]%T%m%n"):
        pattern_(pattern)
        {}
        //对msg进行格式化
        void format(std::ostream&out,Message &msg);
        std::string format(Message &msg);
        //对格式化规则字符串进行解析
        bool parsePatten();
        private:
        std::string pattern_;//格式化规则字符串
        std::vector<FormatItem::ptr> items_;//?
    };
    
}